from django.db import models
from django.template.defaultfilters import escape
from hakaze import settings

# Create your models here.

class Category(models.Model):
    name = models.CharField(maxlength=128)
    priority = models.IntegerField()
    class Admin:
        pass

class Channel(models.Model):
    codename = models.CharField(maxlength=50,primary_key=True)
    name = models.CharField(maxlength=128)
    parent = models.ForeignKey('self',blank=True,null=True)
    description = models.TextField(blank=True,null=True)
    newthreadposts = models.TextField(blank=True,null=True)
    category = models.ForeignKey(Category)
    priority = models.IntegerField()
    class Admin:
        pass

    def get_path(self):
        path = [self]
        parent = self.parent
        while parent:
           path.insert(0,parent)
           parent = parent.parent
        return path

    def get_newthreadposts(self):
        tl = []
        if self.newthreadposts:
            for id in self.newthreadposts.split(','):
                tl.append(Thread.objects.get(id=id))
            return tl

    def set_codename(self,name):
        self.codename = escape(name.replace(' ','_').lower())

    def __str__(self):
        return "%s : %s" % (self.codename,self.name)

    def get_thread(self,t_id):
        return self.thread_set.all().order_by('datecreated')[int(t_id)-1]

class Thread(models.Model):
    title = models.CharField(maxlength=128)
#    description = models.TextField(blank=True,null=True)
    channel = models.ForeignKey(Channel)
    datecreated = models.DateTimeField()
    is_locked = models.BooleanField(default=False)
    class Admin:
        pass

    def run_caching(self):
        pass

    def get_idinchannel(self):
        """
           This is one heck of an ugly query
        """
        retval = 1
        try:
            for p in self.thread_id_cache:
                if self.id == p['id']:
                   return str(retval)
                retval += 1   
        except AttributeError:
            self.thread_id_cache = self.channel.thread_set.all().order_by('datecreated').values('id')
            for p in self.thread_id_cache:
                if self.id == p['id']:
                   return str(retval)
                retval += 1
        return "error"

    def getlatestposts(self,count=5):
        return self.post_set.all().order_by('-datetime')[:count]

    def getlatestposts_for_threadview(self,count=5):
        retval = list(self.post_set.all().order_by('-datetime')[:count])
        try:
           retval.remove(self.getfirstpost()[0]) 
        except:
           pass
        return retval

    def getfirstpost(self):
        return Post.objects.filter(thread=self)[:1]

    def bump_post(self,po):
        ntp = []
        if self.channel.newthreadposts:
           ntp = self.channel.newthreadposts.split(',')
        if str(po.thread.id) in ntp:
           ntp.remove(str(po.thread.id))
        ntp.insert(0,str(po.thread.id))
        if len(ntp) > 40:
           ntp.pop()
        self.channel.newthreadposts = ','.join(ntp)
        self.channel.save()

    def save(self):
        if not self.datecreated:
            import datetime
            self.datecreated = datetime.datetime.now()
        super(Thread,self).save()

    def get_post(self,post_id):
        return self.post_set.all().order_by('datetime')[int(post_id)-1]

    def __str__(self):
        return "ID %s : %s" % (self.id,self.title)

class Post(models.Model):
    name = models.CharField(maxlength=50,blank=True,null=True)
    tripcode = models.CharField(maxlength=10,blank=True,null=True)
    contents = models.TextField(blank=True,null=True)
    link = models.CharField(maxlength=50,blank=True,null=True)
    ip = models.IPAddressField()
    http_x_forwarded_for = models.CharField(maxlength=50,blank=True,null=True)
    datetime = models.DateTimeField()
    thread = models.ForeignKey(Thread)
    is_deleted = models.BooleanField(default=False)


    def get_name(self):
        if not self.name: return u"Anonymous"
        return unicode(self.name,'utf-8')

    def get_tripcode(self):
        if not self.tripcode: return u" "
        return unicode(self.tripcode,'utf-8')

    def run_caching(self):
        pass

    def get_idinthread(self):
        """
           This is one heck of an ugly query
        """
        retval = 1
        try:
            for p in self.posts_id_cache:
                if self.id == p['id']:
                   return str(retval)
                retval += 1
        except AttributeError:
            self.posts_id_cache = self.thread.post_set.all().order_by('datetime').values('id')
            for p in self.posts_id_cache:
                if self.id == p['id']:
                   return str(retval)
                retval += 1
        return "error"

    def set_poster(self,input):
        import md5, binascii
        if input.count('#') >= 3:
            input = "#".join(input.split('#')[:2])
        if input.count('#') == 1:
            name,tripkey = input.split('#')
            hash = binascii.b2a_base64(md5.new(name + tripkey).digest())[:9]
            self.name,self.tripcode = name,hash
        elif input.count('#') == 2:
            name,tripkey,seckey = input.split('#')
            serverkey = settings.TRIPCODE_KEY
            hash = binascii.b2a_base64(md5.new(name + tripkey + seckey + serverkey).digest())[:9]
            self.name,self.tripcode = name,hash
        elif input.count('!'):
            self.name = input[0:input.find('!')]
        else:
            self.name = input

    def save(self):
        if self.thread.is_locked: return
        if not self.datetime:
            import datetime
            self.datetime = datetime.datetime.now()
        super(Post,self).save()
        self.thread.bump_post(self)
        if self.thread.post_set.count >= 1000:
           self.thread.is_locked = True

    def __str__(self):
        return "%s" % self.id
